// 这个模块实现了异常机制
// 使用 `cond` 来控制你的异常流，比如：
//
//     try {
//       cond(1 === 2, BadRequestError, "not equal")
//       cond(2 === 2, ForbiddenError,  "forbidden")
//     } catch (e) {
//       console.log(e.message) 
//     }

export function cond(condition: boolean, 
                     ErrorClass: { new (m?: string): BbsError }, message?: string) {
  if (!condition) {
    if (message) {
      throw new ErrorClass(message)
    }
    throw new ErrorClass()
  }
}

export class BbsError {
  public name: string
  public statusCode: number
  public message: string
  public stack: string

  constructor(message: string) {
    this.name = this.constructor.name
    this.statusCode = -1
    this.message = message
    this.stack = (new Error(message)).stack
    // if (typeof Error.captureStackTrace === 'function') {
    //   Error.captureStackTrace(this, this.constructor)
    // } else { 
    //   this.stack = (new Error(message)).stack 
    // }
  }
}

export class BadRequestError extends BbsError {
  constructor(message = 'Bad Request') {
    super(message)
    this.statusCode = 400
  }
}

export class UnauthorizedError extends BbsError {
  constructor(message = 'Unauthorized') {
    super(message)
    this.statusCode = 401
  }
}

export class ForbiddenError extends BbsError {
  constructor(message = 'Forbidden') {
    super(message)
    this.statusCode = 403
  }
}

export class NotFoundError extends BbsError {
  constructor(message = 'Not Found') {
    super(message)
    this.statusCode = 404
  }
}

export class MethodNotAllowedError extends BbsError {
  constructor(message = 'Method Not Allowed') {
    super(message)
    this.statusCode = 405
  }
}

export class NotAcceptableError extends BbsError {
  constructor(message = 'Not Acceptable') {
    super(message)
    this.statusCode = 406
  }
}

export class ProxyAuthenticationRequiredError extends BbsError {
  constructor(message = 'Proxy Authentication Required') {
    super(message)
    this.statusCode = 407
  }
}

export class RequestTimeoutError extends BbsError {
  constructor(message = 'Request Timeout') {
    super(message)
    this.statusCode = 405
  }
}

export class ConflitError extends BbsError {
  constructor(message = 'Conflit') {
    super(message)
    this.statusCode = 409
  }
}

export class InternalServerError extends BbsError {
  constructor(message = 'Internal Server Error') {
    super(message)
    this.statusCode = 500
  }
}

export class BadGatewayError extends BbsError {
  constructor(message = 'Bad Gateway') {
    super(message)
    this.statusCode = 502
  }
}

export class GatewayTimeoutError extends BbsError {
  constructor(message = 'Gateway Timeout') {
    super(message)
    this.statusCode = 504
  }
}
